﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinBookKeeping.Models;
using WinBookKeeping.Utility;

namespace WinBookKeeping
{
    public partial class FrmWeekStatistics : Form
    {
        private const decimal ABNORMAL_THRESHOLD = 1.5M; // 异常消费阈值（平均值的1.5倍）
        private const decimal SAVING_THRESHOLD = 0.8M;   // 节约阈值（平均值的0.8倍）
        private const int TREND_WEEKS = 4;               // 趋势分析周数

        public FrmWeekStatistics()
        {
            InitializeComponent();
        }
        //本周收入 支出 收支
        decimal thisWeekIn = 0.00M,
                thisWeekEx = 0.00M,
                thisWeekInEx = 0.00M;
        //总收支列表
        List<RecordInfo> recordList = new List<RecordInfo>();
        //周统计数据列表
        List<WeekStatInfo> weekStatList = new List<WeekStatInfo>();

        private async void FrmWeekStatistics_Load(object sender, EventArgs e)
        {
            //按周统计数据
            await StatisticsData();
            //分析消费行为
            AnalyzeConsumptionBehavior();
        }

        private async Task StatisticsData()
        {
            lvInExDataList.Items.Clear();
            //加载所有收支记录
            await LoadAllRecordList();
            //按周统计收支数据并加载列表
            StatisticsWeekList();
            //加载本周收支数据
            LoadStatInfo();
        }

        private async Task LoadAllRecordList()
        {
            //重置
            thisWeekIn = 0.00M;
            thisWeekEx = 0.00M;
            thisWeekInEx = 0.00M;
            recordList = await CommonHelper.GetAllRecordList();
        }

        private void StatisticsWeekList()
        {
            CultureInfo ci = new CultureInfo("zh-CN");
            weekStatList.Clear();
            //筛选出日期列表
            List<string> ListDate = recordList.Select(r => r.RecordTime.ToString("yyyy-MM-dd")).Distinct().ToList();
            //获取年份列表
            List<int> years = ListDate.Select(d => DateTime.Parse(d).Year).Distinct().ToList();
            //本周的周数
            int thisWeek = GetWeek(DateTime.Now, ci);
            //按周统计数据列表--遍历年列表--日期列表--周列表
            foreach (int year in years)
            {
                //获取当前年份日期列表
                var dateList = ListDate.Where(d => DateTime.Parse(d).Year == year);
                //筛选出当年的收支记录
                var yrecordList = recordList.Where(r => r.RecordTime.Year == year);
                //获取当前年份周列表
                List<int> yearWeeks = dateList.Select(d => GetWeek(DateTime.Parse(d), ci)).Distinct().ToList();
                //统计周列表
                foreach (int week in yearWeeks)
                {
                    decimal weekinTotal = 0.00M,
                            weekexTotal = 0.00M,
                            weekinexTotal = 0.00M;
                    //当前周的收支记录
                    var wrecordList = yrecordList.Where(r => GetWeek(r.RecordTime, ci) == week);
                    foreach (var record in wrecordList)
                    {
                        if (record.ItemType == "收入")
                        {
                            weekinTotal += record.Money;
                        }
                        else
                        {
                            weekexTotal += record.Money;
                        }
                    }
                    weekinexTotal = weekinTotal - weekexTotal;
                    if (week == thisWeek)//本周的收支情况
                    {
                        thisWeekEx = weekexTotal;
                        thisWeekIn = weekinTotal;
                        thisWeekInEx = weekinexTotal;
                    }
                    //封装周统计数据
                    WeekStatInfo weekInfo = new WeekStatInfo()
                    {
                        Year = year.ToString(),
                        WeekNumber = week.ToString(),
                        InTotal = weekinTotal,
                        ExTotal = weekexTotal,
                        InExTotal = weekinexTotal
                    };
                    weekStatList.Add(weekInfo);
                }
            }
            //加载数据列表
            if (weekStatList.Count > 0)
            {
                foreach (WeekStatInfo item in weekStatList)
                {
                    ListViewItem li = new ListViewItem();
                    li.Text = item.Year;
                    li.SubItems.Add(item.WeekNumber);
                    li.SubItems.Add("￥" + item.InTotal.ToString("0.00"));
                    li.SubItems.Add("￥" + item.ExTotal.ToString("0.00"));
                    li.SubItems.Add("￥" + item.InExTotal.ToString("0.00"));
                    lvInExDataList.Items.Add(li);
                }
            }
        }

        //本周收支数据加载
        private void LoadStatInfo()
        {
            lblTWeekIn.Text = "￥" + thisWeekIn.ToString("0.00") + " 元";
            lblTWeekEx.Text = "￥" + thisWeekEx.ToString("0.00") + " 元";
            lblTWeekInEx.Text = "￥" + thisWeekInEx.ToString("0.00") + " 元";
        }

        //获取当前时间处于第几周
        private int GetWeek(DateTime dt, CultureInfo ci)
        {
            return ci.Calendar.GetWeekOfYear(dt, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
        }

        private void btnStatistic_Click_1(object sender, EventArgs e)
        {
            StatisticsData();
            AnalyzeConsumptionBehavior();
        }

        //分析消费行为
        private void AnalyzeConsumptionBehavior()
        {
            if (weekStatList.Count == 0) return;

            var analysis = new StringBuilder();

            // 1. 计算平均周支出
            decimal avgWeeklyExpense = weekStatList.Average(d => d.ExTotal);

            // 2. 分析本周支出
            if (thisWeekEx > avgWeeklyExpense * ABNORMAL_THRESHOLD)
            {
                analysis.AppendLine($"⚠️ 本周支出（￥{thisWeekEx:0.00}）显著高于平均周支出（￥{avgWeeklyExpense:0.00}），建议控制支出。");
            }
            else if (thisWeekEx < avgWeeklyExpense * SAVING_THRESHOLD)
            {
                analysis.AppendLine($"✅ 本周支出（￥{thisWeekEx:0.00}）低于平均周支出（￥{avgWeeklyExpense:0.00}），继续保持！");
            }

            // 3. 分析消费趋势
            var recentWeeks = weekStatList.OrderByDescending(d => d.Year + d.WeekNumber).Take(TREND_WEEKS).ToList();
            if (recentWeeks.Count >= 3)
            {
                var trend = AnalyzeTrend(recentWeeks);
                analysis.AppendLine(trend);
            }

            // 4. 分析异常消费
            var abnormalWeeks = weekStatList.Where(d => d.ExTotal > avgWeeklyExpense * ABNORMAL_THRESHOLD).ToList();
            if (abnormalWeeks.Any())
            {
                analysis.AppendLine("\n📊 异常消费提醒：");
                foreach (var week in abnormalWeeks)
                {
                    analysis.AppendLine($"• {week.Year}年第{week.WeekNumber}周 支出 ￥{week.ExTotal:0.00}，超出平均周支出 {((week.ExTotal / avgWeeklyExpense - 1) * 100):0.0}%");
                }
            }

            // 5. 生成节约建议
            analysis.AppendLine("\n💡 节约建议：");
            if (thisWeekEx > avgWeeklyExpense)
            {
                analysis.AppendLine($"• 本周支出较高，建议减少非必要支出");
            }
            if (weekStatList.Count >= 4)
            {
                var monthlyAvg = weekStatList.TakeLast(4).Average(d => d.ExTotal);
                if (monthlyAvg > avgWeeklyExpense)
                {
                    analysis.AppendLine($"• 近四周平均周支出（￥{monthlyAvg:0.00}）高于历史平均，建议控制日常开销");
                }
            }

            // 6. 收入支出比分析
            if (thisWeekIn > 0)
            {
                decimal incomeExpenseRatio = thisWeekEx / thisWeekIn;
                if (incomeExpenseRatio > 0.8M)
                {
                    analysis.AppendLine($"• 本周支出占收入比例较高（{incomeExpenseRatio:P0}），建议适当控制支出");
                }
            }

            // 显示分析结果
            txtAnalysis.Text = analysis.ToString();
        }

        private string AnalyzeTrend(List<WeekStatInfo> recentWeeks)
        {
            var trend = new StringBuilder();
            trend.AppendLine("\n📈 消费趋势分析：");

            // 计算趋势
            var expenses = recentWeeks.Select(d => d.ExTotal).ToList();
            bool isIncreasing = true;
            bool isDecreasing = true;

            for (int i = 1; i < expenses.Count; i++)
            {
                if (expenses[i] <= expenses[i - 1]) isIncreasing = false;
                if (expenses[i] >= expenses[i - 1]) isDecreasing = false;
            }

            if (isIncreasing)
            {
                trend.AppendLine("• 近期支出呈上升趋势，请注意控制支出");
            }
            else if (isDecreasing)
            {
                trend.AppendLine("• 近期支出呈下降趋势，继续保持！");
            }
            else
            {
                trend.AppendLine("• 近期支出波动较大，建议保持稳定消费习惯");
            }

            // 计算波动率
            decimal maxExpense = expenses.Max();
            decimal minExpense = expenses.Min();
            decimal volatility = (maxExpense - minExpense) / minExpense;

            if (volatility > 0.5M)
            {
                trend.AppendLine($"• 支出波动较大（波动率 {volatility:P0}），建议保持稳定消费习惯");
            }

            return trend.ToString();
        }

        private void lblTWeekEx_Click(object sender, EventArgs e)
        {

        }
    }
}
